package com.apestech.formwork.xml.core;

import com.apestech.formwork.xml.core.exec.FieldMapping;
import com.apestech.formwork.xml.core.exec.SingleNode;
import com.apestech.formwork.xml.core.var.NodeVarExcute;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.run.datamapper.SingleDataMappingModule;
import com.apestech.framework.run.modul.ExecListParam;
import com.apestech.framework.xml.pub.core.ElementUtil;
import org.dom4j.Element;

import java.util.ArrayList;

/**
 * 赋值新的NODE，注意这里的NODE入参为源NODE<br>
 * XML NODE内容要求：  <br>
 *   1）TEXT+CDATA组合描述结点包括的内容<br>
 *   2）存在列表，每个列表里的内容为一个子结点<br>
 *   3）不允许同一个结点里的内容包括文本+结点的组合<br>
 *   4）属性类为执行控制参数类<br>
 *
 * @author hup
 * @create 2018-03-23-10:04
 */
public class NodeExec extends ElementUtil {

    private Element node;
    private JSONObject data;
    private NodeBase nodeInfo;
    private JSONObject attr=null;
    private String name;

    public NodeExec(Element node){
        this.node=node;
        this.nodeInfo=new NodeBase(this.node);
        this.nodeInfo.getNodeInfo();
        this.attr=this.nodeInfo.getAttr();
        this.name=this.node.getName();
    }

    public void setData(JSONObject data){
        this.data=data;
    }

    /**
     * 结点命令执行
     * @return
     * @throws Exception
     */
    public Object exec() throws Exception {
        if(this.attr!=null){
            String type = this.node.getName();
            if(type!=null){
                if((NodeVar.getMAPPING()).equals(type)){
                    FieldMapping mapping=new FieldMapping(this.node);
                    return mapping.getMapping(this.data);
                } else if((NodeVarExcute.getCONDITION()).equals(type)){
                    return getExecProcessParam(this.node);
                }
            }
        } else if((NodeVarExcute.getEXECUTION()).equals(this.name)) {
            return getExecution();
        }
        return null;
    }

    private ArrayList<SingleNode> getExecution() throws Exception {
        ArrayList<SingleNode> nlist=new ArrayList<SingleNode>();
        ArrayList<Element> nodes=nodeInfo.getNodes();
        int len=nodes.size();
        for(int i=0; i<len; i++){
            Element e=nodes.get(i);
            SingleNode snode=new SingleNode(e);
            snode.expain();
            nlist.add(snode);
        }
        return nlist;
    }

    /**
     * 获取执行的步骤参数信息
     * @param ele
     * @return
     * @throws Exception
     */
    private ExecListParam getExecProcessParam(Element ele) throws Exception {
        NodeBase nInfo=new NodeBase(ele);
        nInfo.getNodeInfo();
        ArrayList<Element> nodes=nInfo.getNodes();
        int len=nodes.size();
        ExecListParam listParam=new ExecListParam();
        for(int i=0; i<len; i++){
            Element n=nodes.get(i);
            NodeBase ni=new NodeBase(n);
            ni.getNodeInfo();
            ArrayList<Element> step=nInfo.getNodes();
            JSONObject nAttr=ni.getAttr();
            if(nAttr!=null){
                String queryId=nAttr.getString(NodeVarExcute.getQueryId());
                String conditionId=nAttr.getString(NodeVarExcute.getConditionId());
                String pricingProcessId=nAttr.getString(NodeVarExcute.getPricingProcessId());
                String ruleEngineId=nAttr.getString(NodeVarExcute.getRuleEngineId());
                String http=nAttr.getString(NodeVarExcute.getHTTP());
                String className=nAttr.getString(NodeVarExcute.getCLASS());
                String method=nAttr.getString(NodeVarExcute.getMETHOD());
                ArrayList<SingleDataMappingModule> out=null;
                ArrayList<SingleDataMappingModule> in=null;

                Element p=n.element(NodeVarExcute.getINPUT());
                if(p!=null){
                    in=(new FieldMapping(p)).getExecParam();
                }
                p=n.element(NodeVarExcute.getOUTPUT());
                if(p!=null){
                    out=(new FieldMapping(p)).getExecParam();
                }
                if(queryId!=null){
                    listParam.addQuery(queryId, in, out);
                } else if(conditionId!=null){
                    listParam.addCondition(conditionId, in, out);
                } else if(pricingProcessId!=null){
                    listParam.addPricingProcess(pricingProcessId, in, out);
                } else if(ruleEngineId!=null){
                    listParam.addRuleEngine(ruleEngineId, in, out);
                } else if(http!=null){
                    listParam.addHttp(http, in, out);
                } else if(className!=null && method!=null){
                    listParam.addMethod(className, method, in, out);
                }
            }
        }
        return listParam;
    }

}
